#include "stdafx.h"

#include <MyFC/Timer.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

namespace My {

VOID CALLBACK TimerProc(HWND hWnd, UINT uMsg, UINT_PTR id, DWORD dwTime)
{
	Timer * pTimer = reinterpret_cast<Timer *>(::GetWindowLong(hWnd, GWL_USERDATA));
	assert(pTimer != 0);
	pTimer->OnTimer();
}

Timer::Timer()
	: m_Delay(1000), m_hWnd(0), m_ID(0)
{
    WNDCLASSEX wcx;
	memset(&wcx, 0, sizeof(wcx));
    wcx.cbSize = sizeof(wcx); 
    wcx.lpszClassName = "My::TimerWindow";  // name of window class
	wcx.lpfnWndProc = ::DefWindowProc;

	RegisterClassEx(&wcx);

	m_hWnd = ::CreateWindowEx(0, "My::TimerWindow", "My::TimerWindow", 0, 0, 0, 0, 0, 0, 0, 0, 0);
	assert(m_hWnd != 0);

	::SetWindowLong(m_hWnd, GWL_USERDATA, reinterpret_cast<LONG>(this));
}

Timer::~Timer()
{
	::DestroyWindow(m_hWnd);
}

void Timer::CreateTimer()
{
	if (m_ID != 0)
		return;
	m_ID = ::SetTimer(m_hWnd, 1, m_Delay, (TIMERPROC) TimerProc);
	assert(m_ID != 0);
}

void Timer::DeleteTimer()
{
	if (m_ID == 0)
		return;
	VERIFY(::KillTimer(m_hWnd, m_ID));
	m_ID = 0;
}

void Timer::Enable(bool on)
{
	if (on)
		CreateTimer();
	else
		DeleteTimer();
}

void Timer::SetDelay(unsigned int d)
{
	if (d != m_Delay) {
		bool on = Enabled();
		if (on)
			DeleteTimer();
		m_Delay = d;
		if (on)
			CreateTimer();
	}
}

void Timer::OnTimer()
{
	DispatchEvent(TimerEvent(* this));
}

} // My
